package xiao_jin.fantastic_journey.core.mixin;

import net.minecraft.entity.Flutterer;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import xiao_jin.fantastic_journey.core.init.ModFluids;

@Mixin(PlayerEntity.class)
public class PlayerEntityMixin {
    @Inject(method = "travel", at = @At("HEAD"), cancellable = true)
    public void onMoving(Vec3d movementInput, CallbackInfo ci) {
        var thiz = (LivingEntity) (Object) this;

        if (thiz.isLogicalSideForUpdatingMovement()) return;
        FluidState fluidState = thiz.getWorld().getFluidState(thiz.getBlockPos());
        if (!ModFluids.isInOil(fluidState)
                || !((LivingEntityAccessor) thiz).invkoeShouldSwimInFluids()
                || thiz.canWalkOnFluid(fluidState)) return;

        var e = thiz.getY();
        thiz.updateVelocity(0.02F, movementInput);
        thiz.move(MovementType.SELF, thiz.getVelocity());
        Vec3d vec3d3;
        if (thiz.getFluidHeight(FluidTags.WATER) > thiz.getSwimHeight())
            thiz.setVelocity(thiz.getVelocity().multiply(0.5));
        else {
            thiz.setVelocity(thiz.getVelocity().multiply(0.5, 0.800000011920929, 0.5));
            vec3d3 = thiz.applyFluidMovingSpeed(thiz.getFinalGravity(), thiz.getVelocity().y <= 0.0, thiz.getVelocity());
            thiz.setVelocity(vec3d3);
        }

        if (thiz.getFinalGravity() != 0.0)
            thiz.setVelocity(thiz.getVelocity().add(0.0, -thiz.getFinalGravity() / 4.0, 0.0));

        vec3d3 = thiz.getVelocity();
        if (!thiz.horizontalCollision || !thiz.doesNotCollide(vec3d3.x, vec3d3.y + 0.6000000238418579 - thiz.getY() + e, vec3d3.z)) {
            thiz.updateLimbs(this instanceof Flutterer);
            ci.cancel();
        }
        thiz.setVelocity(vec3d3.x, 0.30000001192092896, vec3d3.z);

        thiz.updateLimbs(this instanceof Flutterer);
        ci.cancel();
    }
}
